package com.ug.common.ratelimit.implementation;

import cn.hutool.core.collection.ListUtil;
import com.ug.common.cache.redis.RedisCacheService;
import com.ug.common.enums.ErrorCode;
import com.ug.common.exception.SystemException;
import com.ug.common.ratelimit.RateLimit;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @Author LY
 * @create 2024/8/6 16:37
 * @Description redis实现限流
 */
@Component
@RequiredArgsConstructor
public class RedisRateLimiter extends AbstractRateLimiter {

    private static final Logger logger = LoggerFactory.getLogger(RedisRateLimiter.class);

    private final RedisCacheService redisCacheService;

    @Override
    public void check(RateLimit rateLimiter) {
        logger.info("Redis限流");
        int maxCount = rateLimiter.maxCount();
        String combineKey = rateLimiter.limitType().generateCombinedKey(rateLimiter);

        Long currentCount;
        try {
            currentCount = redisCacheService.rateLimiterLua(ListUtil.of(combineKey), maxCount, rateLimiter.time());
            logger.info("限制请求:{}, 当前请求次数:{}, 缓存key:{}", combineKey, currentCount, rateLimiter.key());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("redis限流器异常：" +  e.getMessage());
        }

        if (currentCount == null) {
            throw new RuntimeException("redis限流器异常，请稍后再试");
        }

        if (currentCount.intValue() > maxCount) {
            throw new SystemException(ErrorCode.COMMON_REQUEST_TOO_OFTEN);
        }
    }

}
